﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;

namespace Super.Common.Strings
{
    public static partial class StringCoder
    {
        public static string FirstUpperCase(string input)
        {
            if (string.IsNullOrEmpty(input))
                return input;

            string firstchar = input.Substring(0, 1);

            return firstchar.ToUpper() + input.Substring(1);
        }

        public static string FirstLowerCase(string input)
        {
            if (string.IsNullOrEmpty(input))
                return input;

            string firstchar = input.Substring(0, 1);

            return firstchar.ToLower() + input.Substring(1);
        }

        /// <summary> http://www.cnblogs.com/sunbingzibo/archive/2008/11/06/1328085.html
        /// 转半角的函数(DBC case) </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>半角字符串</returns>
        ///<remarks>
        ///全角空格为12288，半角空格为32
        ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
        ///</remarks>
        public static string ToDBC(string input)
        {
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 12288)
                {
                    c[i] = (char)32;
                    continue;
                }
                if (c[i] > 65280 && c[i] < 65375)
                    c[i] = (char)(c[i] - 65248);
            }
            return new string(c);
        }

        /// <summary>
        /// http://www.cnblogs.com/sunbingzibo/archive/2008/11/06/1328085.html
        /// 转全角的函数(SBC case)
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>全角字符串</returns>
        ///<remarks>
        ///全角空格为12288，半角空格为32
        ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
        ///</remarks>
        public static string ToSBC(string input)
        {
            //半角转全角：
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 32)
                {
                    c[i] = (char)12288;
                    continue;
                }
                if (c[i] < 127)
                    c[i] = (char)(c[i] + 65248);
            }
            return new string(c);
        }

        //public static string To

        /// <summary>
        /// Byte2s the string.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string ByteToString(byte[] value)
        {
            lock (typeof(StringCoder))
            {
                if (value == null)
                    return null;

                MemoryStream stream = new MemoryStream(value);
                StreamReader reader = new StreamReader(stream);
                return reader.ReadToEnd();
            }
        }

        public static string ByteToString(byte[] value, Encoding encoding)
        {
            lock (typeof(StringCoder))
            {
                if (value == null)
                    return null;

                MemoryStream stream = new MemoryStream(value);
                StreamReader reader = new StreamReader(stream, encoding);
                return reader.ReadToEnd();
            }
        }


        /// <summary>
        /// String2s the byte.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static byte[] StringToByte(string value)
        {
            lock (typeof(StringCoder))
            {
                if (value == null)
                    return null;

                MemoryStream stream = new MemoryStream();
                StreamWriter writer = new StreamWriter(stream);
                writer.Write(value);
                writer.Flush();
                return stream.ToArray();
            }
        }

        public static byte[] StringToByte(string value, Encoding encoding)
        {
            lock (typeof(StringCoder))
            {
                if (value == null)
                    return null;

                MemoryStream stream = new MemoryStream();
                StreamWriter writer = new StreamWriter(stream, encoding);
                writer.Write(value);
                writer.Flush();
                return stream.ToArray();
            }
        }

        /// <summary>
        /// 返回十六进制代表的字符串
        /// </summary>
        /// <param name="mHex"></param>
        /// <returns></returns>
        public static string HexStringToString(string mHex)
        {
            mHex = mHex.Replace(" ", "");
            if (mHex.Length <= 0) return "";

            byte[] vBytes = new byte[mHex.Length / 2];
            for (int i = 0; i < mHex.Length; i += 2)
                if (!byte.TryParse(mHex.Substring(i, 2),
                    System.Globalization.NumberStyles.HexNumber, null, out vBytes[i / 2]))
                    vBytes[i / 2] = 0;

            return Encoding.Default.GetString(vBytes);
        }

        private static char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        public static string ByteToHexString(byte[] bytes)
        {
            char[] chars = new char[bytes.Length * 2];
            for (int i = 0; i < bytes.Length; i++)
            {
                int b = bytes[i];
                chars[i * 2] = hexDigits[b >> 4];
                chars[i * 2 + 1] = hexDigits[b & 0xF];
            }
            return new string(chars);
        }

        public static string ByteToAsciiStrng(byte[] bytes)
        {
            StringBuilder builder = new StringBuilder();

            foreach (byte b in bytes)
            {
                if (b >= 32 && b <= 127)
                    builder.Append(System.Text.Encoding.UTF8.GetString(new byte[] { b }));
                else
                    builder.Append(".");
            }

            return builder.ToString();
        }

        /// <summary>
        /// 使用UTF8对byte解码，得到string
        /// </summary>
        /// <param name="characters">Unicode Byte Array to be converted to String</param>
        /// <returns>String converted from Unicode Byte Array</returns>
        public static string UTF8ByteToString(byte[] value)
        {
            lock (typeof(StringCoder))
            {
                if (value == null)
                    return null;

                UTF8Encoding encoding = new UTF8Encoding();
                string constructedString = encoding.GetString(value);
                return (constructedString);
            }
        }
        /// <summary>
        /// 使用UTF8对string编码，得到byte
        /// </summary>
        /// <param name="pXmlString"></param>
        /// <returns></returns>
        public static byte[] UTF8StringToByte(string value)
        {
            lock (typeof(StringCoder))
            {
                if (value == null)
                    return null;

                UTF8Encoding encoding = new UTF8Encoding();
                Byte[] byteArray = encoding.GetBytes(value);
                return byteArray;
            }
        }

        /// <summary>
        /// Dot2s the long IP.
        /// </summary>
        /// <param name="dotIP">The dot IP.</param>
        /// <returns></returns>
        public static long IPToLong(string dotIP)
        {
            lock (typeof(StringCoder))
            {
                string[] subIP = dotIP.Split('.');
                //IP Address = w.x.y.z 
                //IP Number = 16777216 * w + 65536 * x + 256 * y + z  
                long ip = 16777216 * Convert.ToInt64(subIP[0]) + 65536 * Convert.ToInt64(subIP[1]) + 256 * Convert.ToInt64(subIP[2]) + Convert.ToInt64(subIP[3]);
                return ip;
            }
        }
        /// <summary>
        /// Longs the I p2 dot.
        /// </summary>
        /// <param name="longIP">The long IP.</param>
        /// <returns></returns>
        public static string LongToIP(long longIP)
        {
            lock (typeof(StringCoder))
            {
                string dotIP = "";
                int subIP = 0;

                long one = longIP / 16777216;
                subIP = Convert.ToInt32(one.ToString("f0")) % 256;
                dotIP = subIP.ToString() + ".";
                long two = longIP / 65536;
                subIP = Convert.ToInt32(two.ToString("f0")) % 256;
                dotIP += subIP.ToString() + ".";
                long three = longIP / 256;
                subIP = Convert.ToInt32(three.ToString("f0")) % 256;
                dotIP += subIP.ToString() + ".";
                long four = longIP % 256;
                subIP = Convert.ToInt32(four.ToString("f0"));
                dotIP += subIP.ToString();
                return dotIP;
            }
        }

        /// <summary>
        ///  自己的算法
        /// </summary>
        /// <param name="Message">The message.</param>
        /// <returns></returns>
        private static string _Base64Code(string value)
        {
            lock (typeof(StringCoder))
            {
                char[] Base64Code = new char[]{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',
                     'U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n',
                     'o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7',
                     '8','9',' ','/','='};
                byte empty = (byte)0;
                System.Collections.ArrayList byteMessage = new System.Collections.ArrayList(System.Text.Encoding.Default.GetBytes(value));
                System.Text.StringBuilder outmessage;
                int messageLen = byteMessage.Count;
                int page = messageLen / 3;
                int use = 0;
                if ((use = messageLen % 3) > 0)
                {
                    for (int i = 0; i < 3 - use; i++)
                        byteMessage.Add(empty);
                    page++;
                }
                outmessage = new System.Text.StringBuilder(page * 4);
                for (int i = 0; i < page; i++)
                {
                    byte[] instr = new byte[3];
                    instr[0] = (byte)byteMessage[i * 3];
                    instr[1] = (byte)byteMessage[i * 3 + 1];
                    instr[2] = (byte)byteMessage[i * 3 + 2];
                    int[] outstr = new int[4];
                    outstr[0] = instr[0] >> 2;
                    outstr[1] = ((instr[0] & 0x03) << 4) ^ (instr[1] >> 4);
                    if (!instr[1].Equals(empty))
                        outstr[2] = ((instr[1] & 0x0f) << 2) ^ (instr[2] >> 6);
                    else
                        outstr[2] = 64;
                    if (!instr[2].Equals(empty))
                        outstr[3] = (instr[2] & 0x3f);
                    else
                        outstr[3] = 64;
                    outmessage.Append(Base64Code[outstr[0]]);
                    outmessage.Append(Base64Code[outstr[1]]);
                    outmessage.Append(Base64Code[outstr[2]]);
                    outmessage.Append(Base64Code[outstr[3]]);
                }
                return outmessage.ToString();
            }
        }
        /// <summary>
        /// 自己的算法
        /// </summary>
        /// <param name="Message">The message.</param>
        /// <returns></returns>
        private static string _Base64Decode(string value)
        {
            lock (typeof(StringCoder))
            {
                if ((value.Length % 4) != 0)
                {
                    throw new ArgumentException("不是正确的BASE64编码，请检查。", "Message");
                }
                if (!System.Text.RegularExpressions.Regex.IsMatch(value, "^[A-Z0-9/ =]*$", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    throw new ArgumentException("包含不正确的BASE64编码，请检查。", "Message");
                }
                string Base64Code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 /=";
                int page = value.Length / 4;
                System.Collections.ArrayList outMessage = new System.Collections.ArrayList(page * 3);
                char[] message = value.ToCharArray();
                for (int i = 0; i < page; i++)
                {
                    byte[] instr = new byte[4];
                    instr[0] = (byte)Base64Code.IndexOf(message[i * 4]);
                    instr[1] = (byte)Base64Code.IndexOf(message[i * 4 + 1]);
                    instr[2] = (byte)Base64Code.IndexOf(message[i * 4 + 2]);
                    instr[3] = (byte)Base64Code.IndexOf(message[i * 4 + 3]);
                    byte[] outstr = new byte[3];
                    outstr[0] = (byte)((instr[0] << 2) ^ ((instr[1] & 0x30) >> 4));
                    if (instr[2] != 64)
                    {
                        outstr[1] = (byte)((instr[1] << 4) ^ ((instr[2] & 0x3c) >> 2));
                    }
                    else
                    {
                        outstr[2] = 0;
                    }
                    if (instr[3] != 64)
                    {
                        outstr[2] = (byte)((instr[2] << 6) ^ instr[3]);
                    }
                    else
                    {
                        outstr[2] = 0;
                    }
                    outMessage.Add(outstr[0]);
                    if (outstr[1] != 0)
                        outMessage.Add(outstr[1]);
                    if (outstr[2] != 0)
                        outMessage.Add(outstr[2]);
                }
                byte[] outbyte = (byte[])outMessage.ToArray(Type.GetType("System.Byte"));
                return System.Text.Encoding.Default.GetString(outbyte);
            }
        }

        /// <summary>
        ///  自己的算法
        /// </summary>
        /// <param name="Message">The message.</param>
        /// <returns></returns>
        public static string Base64Code(string value)
        {
            lock (typeof(StringCoder))
            {
                return Convert.ToBase64String(StringToByte(value));
            }
        }
        /// <summary>
        /// 自己的算法
        /// </summary>
        /// <param name="Message">The message.</param>
        /// <returns></returns>
        public static string Base64Decode(string value)
        {
            lock (typeof(StringCoder))
            {
                byte[] returnValue = Convert.FromBase64String(value);
                return ByteToString(returnValue);
            }
        }

        /// <summary>
        /// 省略符缩减字符串
        /// </summary>
        /// <returns></returns>
        public static string StringTrim(string value, int length)
        {
            //如果是中文 12 ->16 需要卡到15

            if (GetStringLength(value) < length)
                return value;
            else
            {
                int lcounter = 0;

                StringBuilder builder = new StringBuilder();

                foreach (char c in value)
                {
                    if (lcounter > length)
                        break;

                    lcounter += GetStringLength(c.ToString());

                    builder.Append(c.ToString());
                }

                builder.Append("..");

                return builder.ToString();
            }
        }

        /// <summary>
        /// 自动分段
        /// </summary>
        /// <param name="value"></param>
        /// <param name="countOfRow"></param>
        /// <param name="countOfLength"></param>
        /// <returns></returns>
        public static string StringTrim(string value, int countOfRow, int countOfLength)
        {
            StringBuilder builder = new StringBuilder();

            int charIndex = 0;

            int rowIndex = 0;

            foreach (char singlevalue in value)
            {
                builder.Append(singlevalue.ToString());

                if (singlevalue == '\r' || singlevalue == 'n')
                    charIndex = 0;
                else
                    charIndex++;

                if (charIndex >= countOfLength)
                {
                    charIndex = 0;

                    builder.Append("\r\n");

                    rowIndex++;
                }

                if (rowIndex >= countOfRow)
                {
                    return builder.ToString();
                }
            }

            return builder.ToString();
        }

        /// <summary>
        /// 添加零 padleft
        /// </summary>
        /// <param name="value"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static string AddZero(string value, int count)
        {
            return value.PadLeft(count, '0');
        }

        public static string AddSpaceAfter(string value, int count)
        {
            return value.PadRight(count, ' ');
        }


        public static int GetStringLength(string value)
        {
            //http://www.zxbc.cn/html/20080803/64009.html

            if (value == null || string.IsNullOrEmpty(value))
                return 0;

            return System.Text.Encoding.GetEncoding("gb2312").GetBytes(value).Length;
        }

        /// <summary>
        /// 获取文字特征值 = 字符串每个字符相乘，转化为小数+字符串长度
        /// char取值范围在0~255，相乘最大值=65025，转化为小数=除以100000。
        /// 保证顺序问题，每个位置再加上权重=当前位置
        /// 防止长度相加超过小数，结果再除以字符串长度
        /// 由于增加了权重，因此最终再除以权重增加的倍数
        /// 保证全局唯一，整数部分加上字符串长度。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static double GetStringEigenValue(string value)
        {
            if (string.IsNullOrEmpty(value))
                return 0;

            double length = value.Length;

            double eigenvalue = 0;

            int index = 1;

            foreach (char str in value)
            {
                double strnum = (double)str;

                eigenvalue += (strnum * strnum) / 100000 * index++;
            }

            //计算由于每个位置添加了权重，导致最终值增加的值

            double weightfactor = (length - 1) * 255 * 255 / 100000 + (length - 1) * (length - 2) * 255 * 255 / 2 / 100000;

            if (weightfactor == 0)
                weightfactor = 1;

            weightfactor = Math.Ceiling(Math.Log10(weightfactor));

            if (weightfactor == 0)
                weightfactor = 1;

            eigenvalue /= weightfactor;

            eigenvalue /= length;

            return length + eigenvalue;
        }

        /// <summary>
        /// 切割 
        /// </summary>
        /// <param name="tables"></param>
        /// <returns></returns>
        public static string[] Devide(string value, int maxLength)
        {
            if (string.IsNullOrEmpty(value))
                return new string[] { value };

            List<string> devides = new List<string>();

            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < value.Length; i++)
            {
                builder.Append(value[i]);

                if ((i + 1) % maxLength == 0)
                {
                    devides.Add(builder.ToString());

                    builder = new StringBuilder();
                }
            }

            if (builder.Length > 0)
                devides.Add(builder.ToString());

            return devides.ToArray();
        }

        private static void test()
        {
            string hello = "213123123";

            foreach (string lien in Devide(hello, 3))
                Console.WriteLine(lien);
        }
    }

}
